package failover

import (
	"basic-go/syntax/webook/internal/service/sms"
	"context"
	"errors"
	"sync/atomic"
)

type FailoverSMSService struct {
	sms []sms.Service

	// 下标
	idx uint64
}

func NewFailoverSMSService(sms []sms.Service) *FailoverSMSService {
	return &FailoverSMSService{
		sms: sms,
	}
}

func (f *FailoverSMSService) Send(ctx context.Context, tpl string, args []string, numbers ...string) error {
	for _, sm := range f.sms {
		err := sm.Send(ctx, tpl, args, numbers...)
		if err == nil {
			return nil
		}
	}
	return errors.New("短信发送失败，所有服务商都尝试了一遍")
}

func (f *FailoverSMSService) SendV1(ctx context.Context, tpl string, args []string, numbers ...string) error {
	idx := atomic.AddUint64(&f.idx, 1)
	length := uint64(len(f.sms))
	for i := idx; i < (idx + length); i++ {
		s := f.sms[i%length]
		err := s.Send(ctx, tpl, args, numbers...)
		switch err {
		case nil:
			return nil
		case context.DeadlineExceeded, context.Canceled:
			{
				return err
			}
		}
	}
	return errors.New("短信发送失败，所有服务商都尝试了一遍")
}
